package centerberg.engine;

import java.awt.Graphics;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;

/**
 * Loads the given imagefile and creates a texture based upon it.
 * Supports three different kinds of textures, scaled, tiled and normal.
 * 
 * @author Andreas Svanberg
 */
public class TextureLoader2
{
    private Map<String, BufferedImage> loadedTextures = new HashMap<String, BufferedImage>();
    
    TextureLoader2()
    {
        
    }
    
    /**
     * Returns the texture with the specified name.
     * 
     * @param name the name of the texture
     * @return     the texture with the specidief name
     */
    public Texture getTexture(String name)
    {
        BufferedImage img = loadedTextures.get(name);
        return new Texture(img, img.getWidth(), img.getHeight());
    }
    
    /**
     * Returns the texture with the specified name tiled to the given size.
     * 
     * @param name   name of the texture
     * @param width  
     * @param height 
     * @return       the tiled texture
     */
    public Texture getTiledTexture(String name, int width, int height)
    {
        BufferedImage tiledImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        BufferedImage textureImage = loadedTextures.get(name);
        
        Graphics g = tiledImage.getGraphics();
        for (int dx = 0; dx < width; dx += textureImage.getWidth())
            for (int dy = 0; dy < height; dy += textureImage.getHeight())
                g.drawImage(textureImage, dx, dy, null);
        
        return new Texture(tiledImage, tiledImage.getWidth(), tiledImage.getHeight());
    }
    
    /**
     * Attempts to load the texture from the given filename. The name must be
     * unique otherwise the previous texture with the given name will be
     * overwritten.
     * 
     * @param name     the name to give the texture
     * @param filename the file to read the image from
     */
    public void loadTexture(String name, String filename)
    {
        loadTexture(name, filename, Texture.Type.NORMAL, 0, 0);
    }
    
    /**
     * Attempts to load the texture from the given filename. The name must be
     * unique otherwise the previous texture with the given name will be
     * overwritten. The type parameter specifies what type of texture it is and
     * w and h specifies the size.
     * 
     * @param name     the name to give the texture
     * @param filename the file to read the image from
     * @param type     the type of texture
     * @param w        the width of the texture
     * @param h        the height of the texture
     * @see Texture.Type
     */
    public void loadTexture(String name, String filename, Texture.Type type, int w, int h)
    {
        try
        {
            BufferedImage fileImage = ImageIO.read(new java.io.File(filename));
            BufferedImage actualImage;
            
            if (type == Texture.Type.SCALED)
            {
                double sx = (double)w / fileImage.getWidth();
                double sy = (double)h / fileImage.getHeight();
                AffineTransform at = new AffineTransform();
                at.scale(sx, sy);
                AffineTransformOp scale = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
                actualImage = scale.filter(fileImage, null);
            }
            else if (type == Texture.Type.TILED)
            {
                actualImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
                Graphics g = actualImage.getGraphics();
                for (int dx = 0; dx < actualImage.getWidth(); dx += fileImage.getWidth())
                    for (int dy = 0; dy < actualImage.getHeight(); dy += fileImage.getHeight())
                        g.drawImage(actualImage, dx, dy, null);
            }
            else
            {
                actualImage = fileImage;
            }
            
            loadedTextures.put(name, actualImage);
        }
        catch (Exception e) { e.printStackTrace(); }
    }
}
